package org.dromara.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.ObjectUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.SysUserMachine;
import org.dromara.system.domain.SysUserPurse;
import org.dromara.system.domain.bo.FundsBo;
import org.dromara.system.domain.bo.HomePagePointsBo;
import org.dromara.system.domain.vo.*;
import org.dromara.system.enums.TimeRadiusEnum;
import org.dromara.system.mapper.SysUserPointsRecordsMapper;
import org.dromara.system.mapper.TradingRecordsMapper;
import org.dromara.system.service.ISysUserMachineService;
import org.dromara.system.service.ISysUserPurseService;
import org.dromara.system.service.ISysUserService;
import org.dromara.system.service.IndexInfoService;
import org.dromara.system.util.TimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@RequiredArgsConstructor
@Service
public class IndexInfoServiceImpl implements IndexInfoService {

    private final ISysUserPurseService sysUserPurseService;
    private final ISysUserService sysUserService;
    private final TradingRecordsMapper tradingRecordsMapper;
    private final ISysUserMachineService sysUserMachineService;
    @Autowired
    private SysUserPointsRecordsMapper sysUserPointsRecordsMapper;

    @Override
    public HomePagePointsVo homePagePoints() {
        Long userId = LoginHelper.getUserId();
        HomePagePointsBo allHomePagePointsBo = HomePagePointsBo.builder()
            .userId(userId).build();
        BigDecimal allPoints = sysUserPointsRecordsMapper.queryHomePagePointsBo(allHomePagePointsBo);

        HomePagePointsBo todayHomePagePointsBo = HomePagePointsBo.builder()
            .userId(userId)
            .startTime(DateUtil.beginOfDay(DateUtil.date()))
            .endTime(DateUtil.endOfDay(DateUtil.date()))
            .build();
        BigDecimal todayPoints = sysUserPointsRecordsMapper.queryHomePagePointsBo(todayHomePagePointsBo);
        return HomePagePointsVo.builder()
            .allPoints(allPoints)
            .todayPoints(todayPoints)
            .build();
    }

    @Override
    public HomePageLotteryInfoVo homePageLotteryInfo() {
        Long userId = LoginHelper.getUserId();
        SysUserPurse sysUserPurse = sysUserPurseService.lambdaQuery().eq(SysUserPurse::getUserId, userId).one();
        BigDecimal lotteryPoints = sysUserPurse.getLotteryPoints();
        SysUserVo sysUserVo = sysUserService.selectUserById(userId);
        BigDecimal dealSumTag = sysUserVo.getDealSumTag();
        return HomePageLotteryInfoVo.builder()
            .lotteryPoints(lotteryPoints)
            .DealSumTag(dealSumTag)
            .targetSum(Convert.toBigDecimal(10000))
            .build();
    }


    @Override
    public TradingStatisticsVo tradingStatistics(FundsBo bo) {
        TradingStatisticsVo tradingStatisticsVo = new TradingStatisticsVo();
        if (ObjectUtil.isNull(bo.getUserId())) {
            bo.setUserId(LoginHelper.getUserId());
        }
        List<SysUserMachine> sysUserMachines = sysUserMachineService.lambdaQuery()
            .eq(SysUserMachine::getBindUserId, bo.getUserId()).list();
        if (CollUtil.isEmpty(sysUserMachines)) {
            return tradingStatisticsVo;
        }
        List<String> sns = sysUserMachines.stream().map(SysUserMachine::getSn).toList();
        BigDecimal totalTradingAmount = tradingRecordsMapper.queryTradingTimeByBindUerId(bo);
        BigDecimal todayTradingAmount = getTradingTimeByBindUerId(TimeRadiusEnum.TODAY, bo);
        BigDecimal currentMonthTradingAmount = getTradingTimeByBindUerId(TimeRadiusEnum.CURRENT_MONTH, bo);
        List<MachineTradingStatisticsVo> machineTradingStatisticsVos = new ArrayList<>();
        sns.forEach(t -> {
            bo.setSn(t);
            BigDecimal totalTradingAmountForSn = tradingRecordsMapper.queryTradingTimeByBindUerId(bo);
            BigDecimal todayTradingAmountForSn = getTradingTimeByBindUerId(TimeRadiusEnum.TODAY, bo);
            BigDecimal currentMonthTradingAmountForSn = getTradingTimeByBindUerId(TimeRadiusEnum.CURRENT_MONTH, bo);
            machineTradingStatisticsVos.add(MachineTradingStatisticsVo.builder()
                .sn(t)
                .snTotalTradingAmount(totalTradingAmountForSn)
                .snTodayTradingAmount(todayTradingAmountForSn)
                .snCurrentMonthTradingAmount(currentMonthTradingAmountForSn).build());
        });
        tradingStatisticsVo.setTotalMachineNum(sns.size());
        tradingStatisticsVo.setTotalTradingAmount(totalTradingAmount);
        tradingStatisticsVo.setTodayTradingAmount(todayTradingAmount);
        tradingStatisticsVo.setCurrentMonthTradingAmount(currentMonthTradingAmount);
        tradingStatisticsVo.setMachineTradingStatisticsVos(machineTradingStatisticsVos);
        return tradingStatisticsVo;
    }

    private BigDecimal getTradingTimeByBindUerId(TimeRadiusEnum today, FundsBo bo) {
        Pair<LocalDateTime, LocalDateTime> pair = TimeUtil.getTimeRadius(today);
        bo.setStart(pair.getKey());
        bo.setEnd(pair.getValue());
        return tradingRecordsMapper.queryTradingTimeByBindUerId(bo);
    }

}
